package com.yc;

import jdk.jfr.DataAmount;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo1  extends  Demo1Parent{
    public Demo1(){

    }
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
       Class c0 =Demo1.class;
        System.out.println(c0); // class com.yc.Demo1



        Demo1 demo1=new Demo1();
       Class c1=demo1.getClass();
       Class c2=Class.forName("com.yc.Demo1");
        System.out.println(c0.getName());//com.yc.Demo1

        System.out.println(c0==c1);//true
        System.out.println(c1==c2);//true


        /*
        * 类的构成元素：
        * 属性
        * 方法
        * 构造方法
        * 块 =》无名构造函数
        * 内部类
        * */

        c0.getFields();//全部公有属性
        c0.getMethods();//全部公有方法
        c0.getConstructors();//构造方法
        c0.getDeclaredClasses();//内部类

        c0.getFields();//全部公有属性
        c0.getField("a");//指定名称的公有属性
        c0.getDeclaredField("a");//指定名称的定义属性
        c0.getDeclaredFields();//所有定义属性
      /*  不带 declared: 获取的是 public 修饰的元素
        带 declared: 获取的是该类定义的元素 所有
*/

        System.out.println("=====全部的公有属性=======");
        for (Field field : c0.getFields()) {
            System.out.println("field="+field);
        }

        System.out.println("=====全部的定义属性=======");
        for (Field field : c0.getDeclaredFields()) {
            System.out.println("field="+field);
        }

        System.out.println("=====当前类的全部属性包括父类非公有=======");
        Class c=c0; //反射类对象
      while (c!=null){
          for (Field field : c.getDeclaredFields()) {
              System.out.println("field="+field);
          }
          //父类
          c=c.getSuperclass();
      }
      User user=new User();
      test(user);

    }

    public String a;
    protected String b;
    private String c;
    String d;

    public static void test(Object obj) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass = obj.getClass();
        //getName 全名
        if("com.yc.User".equals(aClass.getName())){
            Field name = aClass.getDeclaredField("name");
            //强制访问，可以访问私有属性 name可能为private
            name.setAccessible(true); //设值强行访问
            name.set(obj,"张三");


            //调用无参方法
            Method hello = aClass.getDeclaredMethod("hello");
            hello.setAccessible(true);
            hello.invoke(obj);
            //调用有参方法
            Method  hello1 = aClass.getDeclaredMethod("hello",String.class);
            hello.setAccessible(true);
            hello1.invoke(obj,"李四");

            System.out.println("obj.toString()="+obj.toString());

            /*String.class是指向String类的Class对象。
            Class对象是Java中用于表示类的元数据的对象，它包含了类的名称、字段、方法等信息。
            通过String.class可以获取String类的相关信息，比如类名、父类、实现的接口等。*/
        }
    }




}
class Demo1Parent{
    public String a1;
    protected String b1;
    private String c1;
    String d1;
}


@Data // 自动生成 get，set,Tostring,equals，hashcode方法
@AllArgsConstructor//全部属性构造函数
@NoArgsConstructor // 无参构造函数
class User{
    String name;
    String pwd;
    String age;

    public void  hello(){
        System.out.println("hello"+name);
    }
    public void  hello(String name){


    }

}
